{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 10.2  XGBoost算法案例实战1 - 金融反欺诈模型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**10.2.1 案例背景**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "信用卡盗刷一般发生在持卡人信息被不法分子窃取后复制卡片进行消费或信用卡被他人冒领后激活消费的情况。一旦发生信用卡盗刷，持卡人和银行都会蒙受一定的经济损失。因此，通过大数据搭建金融反欺诈模型对银行来说尤为重要。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**10.2.2 模型搭建**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1.读取数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>换设备次数</th>\n",
       "      <th>支付失败次数</th>\n",
       "      <th>换IP次数</th>\n",
       "      <th>换IP国次数</th>\n",
       "      <th>交易金额</th>\n",
       "      <th>欺诈标签</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>11</td>\n",
       "      <td>3</td>\n",
       "      <td>5</td>\n",
       "      <td>28836</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>5</td>\n",
       "      <td>6</td>\n",
       "      <td>1</td>\n",
       "      <td>4</td>\n",
       "      <td>21966</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>6</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>18199</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>5</td>\n",
       "      <td>8</td>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "      <td>24803</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>7</td>\n",
       "      <td>10</td>\n",
       "      <td>5</td>\n",
       "      <td>0</td>\n",
       "      <td>26277</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   换设备次数  支付失败次数  换IP次数  换IP国次数   交易金额  欺诈标签\n",
       "0      0      11      3       5  28836     1\n",
       "1      5       6      1       4  21966     1\n",
       "2      6       2      0       0  18199     1\n",
       "3      5       8      2       2  24803     1\n",
       "4      7      10      5       0  26277     1"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "df = pd.read_excel('信用卡交易数据.xlsx')\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2.提取特征变量和目标变量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 通过如下代码将特征变量和目标变量单独提取出来，代码如下：\n",
    "X = df.drop(columns='欺诈标签') \n",
    "y = df['欺诈标签']    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "3.划分训练集和测试集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 提取完特征变量后，通过如下代码将数据拆分为训练集及测试集：\n",
    "from sklearn.model_selection import train_test_split\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=123)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "4.模型训练及搭建"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "XGBClassifier(base_score=0.5, booster='gbtree', colsample_bylevel=1,\n",
       "              colsample_bytree=1, gamma=0, learning_rate=0.05, max_delta_step=0,\n",
       "              max_depth=3, min_child_weight=1, missing=None, n_estimators=100,\n",
       "              n_jobs=1, nthread=None, objective='binary:logistic',\n",
       "              random_state=0, reg_alpha=0, reg_lambda=1, scale_pos_weight=1,\n",
       "              seed=None, silent=True, subsample=1)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 划分为训练集和测试集之后，就可以引入XGBoost分类器进行模型训练了，代码如下：\n",
    "from xgboost import XGBClassifier\n",
    "clf = XGBClassifier(n_estimators=100, learning_rate=0.05)\n",
    "clf.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**10.2.3 模型预测及评估**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1,\n",
       "       1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0,\n",
       "       0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0,\n",
       "       0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0,\n",
       "       0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,\n",
       "       0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0,\n",
       "       0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0,\n",
       "       1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n",
       "       0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0,\n",
       "       1, 1], dtype=int64)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 模型搭建完毕后，通过如下代码预测测试集数据：\n",
    "y_pred = clf.predict(X_test)\n",
    "\n",
    "y_pred  # 打印预测结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>预测值</th>\n",
       "      <th>实际值</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   预测值  实际值\n",
       "0    0    1\n",
       "1    1    1\n",
       "2    1    1\n",
       "3    0    0\n",
       "4    0    1"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 通过和之前章节类似的代码，我们可以将预测值和实际值进行对比：\n",
    "a = pd.DataFrame()  # 创建一个空DataFrame \n",
    "a['预测值'] = list(y_pred)\n",
    "a['实际值'] = list(y_test)\n",
    "a.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.875"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 可以看到此时前五项的预测准确度为60%，如果想看所有测试集数据的预测准确度，可以使用如下代码：\n",
    "from sklearn.metrics import accuracy_score\n",
    "score = accuracy_score(y_pred, y_test)\n",
    "score"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.875"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 我们还可以通过XGBClassifier()自带的score()函数来查看模型预测的准确度评分，代码如下，获得的结果同样是0.875。\n",
    "clf.score(X_test, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0.87444973 0.12555024]\n",
      " [0.0398438  0.9601562 ]\n",
      " [0.00791121 0.9920888 ]\n",
      " [0.8734765  0.1265235 ]\n",
      " [0.8658593  0.13414067]]\n"
     ]
    }
   ],
   "source": [
    "# XGBClassifier分类器本质预测的并不是准确的0或1的分类，而是预测其属于某一分类的概率，可以通过predict_proba()函数查看预测属于各个分类的概率，代码如下：\n",
    "y_pred_proba = clf.predict_proba(X_test)\n",
    "print(y_pred_proba[0:5])  # 查看前5个预测的概率"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 此时的y_pred_proba是个二维数组，其中第一列为分类为0（也即非欺诈）的概率，第二列为分类为1（也即欺诈）的概率，因此如果想查看欺诈（分类为1）的概率，可采用如下代码：\n",
    "# y_pred_proba[:,1]  # 分类为1的概率"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 下面我们利用4.3节相关代码绘制ROC曲线来评估模型预测的效果：\n",
    "from sklearn.metrics import roc_curve\n",
    "fpr, tpr, thres = roc_curve(y_test, y_pred_proba[:,1])\n",
    "import matplotlib.pyplot as plt\n",
    "plt.plot(fpr, tpr)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.8661377275963789"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 通过如下代码求出模型的AUC值：\n",
    "from sklearn.metrics import roc_auc_score\n",
    "score = roc_auc_score(y_test, y_pred_proba[:,1])\n",
    "\n",
    "score"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.2557377 , 0.2590164 , 0.18360655, 0.2557377 , 0.04590164],\n",
       "      dtype=float32)"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 我们可以通过查看各个特征的特征重要性(feature importance)来得出信用卡欺诈行为判断中最重要的特征变量：\n",
    "clf.feature_importances_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>特征名称</th>\n",
       "      <th>特征重要性</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>支付失败次数</td>\n",
       "      <td>0.259016</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>换设备次数</td>\n",
       "      <td>0.255738</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>换IP国次数</td>\n",
       "      <td>0.255738</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>换IP次数</td>\n",
       "      <td>0.183607</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>交易金额</td>\n",
       "      <td>0.045902</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     特征名称     特征重要性\n",
       "1  支付失败次数  0.259016\n",
       "0   换设备次数  0.255738\n",
       "3  换IP国次数  0.255738\n",
       "2   换IP次数  0.183607\n",
       "4    交易金额  0.045902"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 通过如下5.2.2节特征重要性相关知识点进行整理，方便结果呈现，代码如下：\n",
    "features = X.columns  # 获取特征名称\n",
    "importances = clf.feature_importances_  # 获取特征重要性\n",
    "\n",
    "# 通过二维表格形式显示\n",
    "importances_df = pd.DataFrame()\n",
    "importances_df['特征名称'] = features\n",
    "importances_df['特征重要性'] = importances\n",
    "importances_df.sort_values('特征重要性', ascending=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**10.2.4 模型参数调优**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import GridSearchCV  \n",
    "parameters = {'max_depth': [1, 3, 5], 'n_estimators': [50, 100, 150], 'learning_rate': [0.01, 0.05, 0.1, 0.2]}  # 指定模型中参数的范围\n",
    "clf = XGBClassifier()  # 构建模型\n",
    "grid_search = GridSearchCV(clf, parameters, scoring='roc_auc', cv=5)  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'learning_rate': 0.05, 'max_depth': 1, 'n_estimators': 100}"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 下面我们将数据传入网格搜索模型并输出参数最优值：\n",
    "grid_search.fit(X_train, y_train)  # 传入数据\n",
    "grid_search.best_params_  # 输出参数的最优值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "XGBClassifier(base_score=0.5, booster='gbtree', colsample_bylevel=1,\n",
       "              colsample_bytree=1, gamma=0, learning_rate=0.05, max_delta_step=0,\n",
       "              max_depth=1, min_child_weight=1, missing=None, n_estimators=100,\n",
       "              n_jobs=1, nthread=None, objective='binary:logistic',\n",
       "              random_state=0, reg_alpha=0, reg_lambda=1, scale_pos_weight=1,\n",
       "              seed=None, silent=True, subsample=1)"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 下面我们根据新的参数建模，首先重新搭建XGBoost分类器，并将训练集数据传入其中：\n",
    "clf = XGBClassifier(max_depth=1, n_estimators=100, learning_rate=0.05)\n",
    "clf.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.8563218390804598\n"
     ]
    }
   ],
   "source": [
    "# 因为我们是通过ROC曲线的AUC评分作为模型评价准则来进行参数调优的，因此通过如下代码我们来查看新的AUC值：\n",
    "y_pred_proba = clf.predict_proba(X_test)\n",
    "from sklearn.metrics import roc_auc_score\n",
    "score = roc_auc_score(y_test, y_pred_proba[:,1])\n",
    "print(score)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "将获得的AUC评分打印出来为：0.856，比原来没有调参前的0.866还略微低了些，有的读者可能会奇怪为什么调参后的结果还不如未调参时的结果，通常来说参数调优出现这种情况的概率较小，这里出现了也正好给大家解释下出现这种情况的原因。\n",
    "\n",
    "出现这种情况的原因是因为交叉验证，我们来简单回顾下5.3节K折交叉验证的思路：它是将原来的测试数据分为K份（这里cv=5，即5份），然后在这K份数据中，选K-1份作为训练数据，剩下的1份作为测试数据，训练K次，获得K个的ROC曲线下的AUC值，然后将K个AUC值取平均，取AUC值的均值为最大情况下的参数为模型的最优参数。注意这里AUC值的获取是基于训练集数据，只不过是将训练集数据中的1/K作为测试集数据，这里的测试集数据并不是真正的测试集数据y_test，这也是为什么参数调优后结果反而不如不调优的结果的原因。实际应用中，通常不太会出现调参结果不如不调参的结果，出现这种情况某种程度也是因为数据量较小的原因（像本案例为1000条数据）。其他关于参数调优的其他一些注意点请参考5.3节，这里不再赘述。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
